//  回调函数: 把函数当成参数传入到另一个函数中 

// ele  运动的元素
// attr 运动的css属性("left" top width height opacity)
// end  运动的终点值 
// aniType  运动的方式 (linear ease-in ease-out)
// fn   回调函数(可以理解为提前决定好 每次运动结束要执行的内容,本次运动结束执行)
function animate(ele, attr, end, aniType = "linear", fn) {
    //  1. 记录盒子的起始位置   2. 记录每次运动之后盒子的位置
    // var cur = ele.offsetLeft;    // 快捷取值

    // if (ele.isAni) return false;
    ele.isAni = true;   // 如果没有运动 => 运动开始

    var cur = parseFloat(getStyle(ele, attr));  //传统的获取非行内样式
    end = parseFloat(end);       // 设置运动的终点值 (可以去单位)

    if (attr === "opacity") {  //opacity (0-1) =>  原值扩大1000倍(0-1000)
        cur *= 1000;
        end *= 1000;
    }

    var speed = 0;  // 1. 没有运动之前初始速度   2. 记录每次运动的速度

    clearInterval(ele.timer);         // 每次启动下一个之前 清除上一个

    // 元素节点的本质 => 对象 => 给对象赋一个不存在的属性名  => 新增该属性到对象中
    ele.timer = setInterval(function () {

        if (aniType == "linear") {  //匀速

            speed = end >= cur ? 20 : -20;   // 每隔10ms运动的距离  (匀速)
        } else if (aniType == "ease-in") { // 加速
            speed = end >= cur ? speed + 2 : speed - 2;
        } else if (aniType == "ease-out") { //缓冲
            // speed = (end - cur) / 10;
            // speed = end >= cur ? Math.ceil(speed) : Math.floor(speed);
            speed = Math.ceil(Math.abs(end - cur) / 10);  //取绝对值 => 向上取值
            speed = end >= cur ? speed : - speed;
        }


        // console.log(speed);

        cur += speed;
        // console.log(cur);

        if (attr === "opacity") {
            ele.style[attr] = cur / 1000;
        } else {
            ele.style[attr] = cur + "px";
        }

        // 问题: 理想情况下 cur == end,但是如果需要运动的距离(终点值 - 起点值) 不是速度的整数倍  => 不会停止
        // 解决方法:   
        // (1)  cur >= end
        // (2)  Math.abs(end - cur) <= Math.abs(speed)
        // 新的问题  => 超出几像素  => 强制到达终点

        // 临界值判断
        if (Math.abs(end - cur) <= Math.abs(speed)) {
            clearInterval(ele.timer);
            ele.isAni = false;
            if (attr === "opacity") {
                ele.style[attr] = end / 1000;
            } else {
                ele.style[attr] = end + "px";
            }

            if (fn) {
                fn();
            }

        }

    }, 10)

}

function getStyle(ele, attr) {
    if (window.getComputedStyle) {
        return window.getComputedStyle(ele)[attr];
    } else {
        return ele.currentStyle[attr];
    }
}
